export {};

/** 泛型与数组类型*/
function returnArray<T>(array:T[]):Array<T>{ // T[] 和 Array<T> 是等价的
  return array;
}

interface Human{
  name:string;
  age: number;
}

let a = returnArray<Human>([{name: 'ahhh', age: 18}, {name: 'ahhh2', other: 123}]);
//↑ TS2322: Type '{ name: string; other: number; }' is not assignable to type 'Human'.
//Object literal may only specify known properties, and 'other' does not exist in type 'Human'.


//--- --- ---

/** <T> 该放外面还是放里面?*/
//√
/*const forEach = <T>(arr: T[], callback: (item: T, index: number) => void) => {
  for (let i = 0; i < arr.length; i++) {
    callback(arr[i], i);
  }
};*/
//
//×
/*type ICallback = <T>(item: T, index: number) => void;
const forEach = <T>(arr: T[], callback: ICallback) => {
  for (let i = 0; i < arr.length; i++) {
    callback(arr[i], i);
  }
};*/
//此时把鼠标移到我们调用的callback的item参数上, 你会发现类型并没有正确推断出
//为什么ts猜不出来呢？
//因为当前写法下我们只有在 callback(arr[i], i) 执行时才能确定 T 的类型
//但是呢 TS 类型检测 并不会执行代码 So... 猜不出来
//
//√
type ICallback<T> = (item: T, index: number) => void;
//↕ 等价
/*interface ICallback<T>{
  (item: T, index: number): void;
}*/
type IForEach = <T>(arr: T[], callback: ICallback<T>) => void;
const forEach:IForEach = (arr,callback) => {
  for (let i = 0; i < arr.length; i++) {
    callback(arr[i], i);
  }
};
forEach([1,'2',3],function(item/**← 把鼠标移到该参数上 可以看到显示的类型*/){

})
